from django.contrib.auth import login
from django.shortcuts import render, redirect, reverse
from django.views import View
from utils.secret import SecretOauth
from django.conf import settings
from QQLoginTool.QQtool import OAuthQQ
from django import http
from utils.response_code import RETCODE
from meiduo_mall.settings.dev import LOGGER, Sina_App_Key, Sina_App_Secret, Sina_REDIRECT_URI
from apps.oauth.models import *
import re
from django_redis import get_redis_connection
from libs.sina.sinaweibopy3 import *


class QQAuthURLView(View):
    def get(self, request):
        """获取QQ登录页面网址"""
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=next)
        login_url = oauth.get_qq_url()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


class QQAuthUserView(View):
    def get(self, request):
        """QQ认证"""
        # 提取code请求参数
        code = request.GET.get('code')
        if not code:
            return http.HttpResponseForbidden('缺少code')

        # 创建工具对象
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            # 使用code向QQ服务器请求access_token
            access_token = oauth.get_access_token(code)

            # 使用access_token向QQ服务器请求openid
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            LOGGER.error(e)
            return http.HttpResponseServerError('OAuth2.0认证失败')

        try:
            # 根据 openid 查询用户是否存在
            oauth_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果openid没绑定美多商城用户
            # 加密 openid--使用itsdangerous
            secret_openid = SecretOauth().dumps({'openid': openid})
            context = {'openid': secret_openid}
            return render(request, 'oauth_callback.html', context)
        else:
            # 如果openid已绑定美多商城用户
            # 保持登陆状态
            qq_user = oauth_user.user
            login(request, qq_user)
            response = redirect(reverse("Contents:index"))

            # 登录时用户名写入到cookie，有效期15天
            response.set_cookie('username', qq_user.username, max_age=3600 * 24 * 15)

            return response

    def post(self, request):
        """未绑定 进行信息绑定"""
        # 接收参数
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        secret_openid = request.POST.get("openid")
        '''
        # 参数校验
        # 判空操作
        if not all([mobile, pwd]):
            return http.HttpResponseForbidden("缺少必填参数!")
        # 数据校验
        if not re.match(r"^1[345789]\d{9}$", mobile):
            return http.HttpResponseForbidden("手机号不合法啊!")

        if not re.match(r"^[0-9A-Za-z]{8,20}$", pwd):
            return http.HttpResponseForbidden("密码不合法啊!")
        # 进行手机验证码校验
        sms_cli = get_redis_connection("sms_code")
        redis_sms_code = sms_cli.get("sms_code_%s" % mobile)
        try:
            sms_cli.delete("sms_code_%s" % mobile)
        except Exception as e:
            LOGGER.error(e)

        if redis_sms_code is None:
            return render(request, 'register.html', {'sms_code_errmsg': '无效的短信验证码'})

        if sms_code != redis_sms_code.decode():
            return render(request, 'register.html', {'sms_code_errmsg': '输入短信验证码有误'})
        '''
        # openid 解密校验
        openid = SecretOauth().loads(secret_openid).get("openid")
        if not openid:
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})

        # 根据手机号查询用户是否存在 存在直接跳转 不存在创建
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 用户不存在,新建用户
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)
        else:
            # 如果用户存在，检查用户密码
            if not user.check_password(pwd):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})

        # 将用户绑定openid
        try:
            OAuthQQUser.objects.create(openid=openid, user=user)

        except Exception as e:
            LOGGER.error(e)
            return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})

        # 保持登陆状态
        login(request, user)  # 设置cookie
        response = redirect(reverse("Contents:index"))
        # 登录时用户名写入到cookie，有效期15天
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        return response


class OAuthSinaURLView(View):
    def get(self, request):
        """获取授权登陆链接"""
        sina_cli = APIClient(Sina_App_Key, Sina_App_Secret, Sina_REDIRECT_URI)
        login_url = sina_cli.get_authorize_url()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})


class SinaAuthUserView(View):
    def get(self, request):
        # sina_callback?code = c53ee024227cdc3558a8ab6627791893
        code = request.GET.get('code')
        if not code:
            return http.HttpResponseForbidden('缺少code')
        sina_cli = APIClient(Sina_App_Key, Sina_App_Secret, Sina_REDIRECT_URI)
        try:
            token = sina_cli.request_access_token(code)
            print("新浪Token：{}".format(token))
            # 设置过期时间
            sina_cli.set_access_token(token, 3600*24)
            uid = token.uid
            # print(sina_cli.is_expires())
        except Exception as e:
            LOGGER.error(e)
            return http.HttpResponseServerError('OAuth2.0认证失败')
        try:
            oauth_user = OAuthSinaUser.objects.get(uid=uid)
        except OAuthSinaUser.DoesNotExist as e:
            LOGGER.error(e)
            secret_openid = SecretOauth().dumps({'openid': token.uid})
            context = {'openid': secret_openid}
            return render(request, 'oauth_callback.html', context)
        else:
            # 如果uuid已绑定美多商城用户
            # 保持登陆状态
            sina_user = oauth_user.user
            login(request, sina_user)
            response = redirect(reverse("Contents:index"))

            # 登录时用户名写入到cookie，有效期15天
            response.set_cookie('username', sina_user.username, max_age=3600 * 24 * 15)

            return response

    def post(self, request):
        mobile = request.POST.get('mobile')
        image_code = request.POST.get('image_code')
        sms_code = request.POST.get('sms_code')
        openid = request.POST.get('openid')
        password = request.POST.get('password')

        # 参数判空
        # 参数校验

        # 解密uid
        openid_dict = SecretOauth().loads(openid)
        if openid_dict is None:
            return http.HttpResponseForbidden('授权信息无效，请重新授权')
        uid = openid_dict.get("openid")
        try:
            user = User.objects.get(mobile=mobile)
        except:
            # 2.如果未使用，则新建用户
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        else:
            # 3.如果已使用，则验证密码
            # 3.1密码正确，则继续执行
            if not user.check_password(password):
                # 3.2密码错误，则提示
                return http.HttpResponseForbidden('手机号已经使用，或密码错误')

        # 4.绑定：新建OAuthSinaUser对象
        OAuthSinaUser.objects.create(
            user=user,
            uid=uid
        )
        # 状态保持
        login(request, user)
        response = redirect(reverse("Contents:index"))
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        # 响应
        return response

